﻿Imports Aricie.DNN.UI.WebControls
Imports System.Globalization
Imports Newtonsoft.Json
Imports Aricie.Collections
Imports System.Linq
Imports Aricie.DNN.Services.Url.FriendlyUrl.Controls.GroupEntities
Imports DotNetNuke.Services.Localization


Namespace Aricie.DNN.Services.Url.FriendlyUrl.Controls

    Public Class UrlGroups
        Inherits PropertyEditorUserControlBase
        Implements IPostBackEventHandler, IScriptControl


        Private _CurrentSettings As FriendlierUrlSettings

        Public ReadOnly Property CurrentSettings As FriendlierUrlSettings
            Get
                if _CurrentSettings Is nothing
                    _CurrentSettings = Me.EditControl.ParentAricieEditor.GetParentEntity(of FriendlierUrlSettings)
                End If
                Return _CurrentSettings
            End Get
        End Property

        Public Property Groups As SerializableList(Of UrlGroup)
            Get
                Return DirectCast(Me.Value, FriendlierUrlRule).Instances
            End Get
            Set(value As SerializableList(Of UrlGroup))
                DirectCast(Me.Value, FriendlierUrlRule).Instances = value
                rUsedGroups.DataSource = Nothing ' on force le rebind
                EditedGroup = -1
            End Set
        End Property

        Public Property GroupsAvailable As List(Of GroupEntities.UIGroup)
            Get
                If ViewState("GroupsAvailable") Is Nothing Then
                    ViewState("GroupsAvailable") = New List(Of GroupEntities.UIGroup)()
                End If
                Return DirectCast(ViewState("GroupsAvailable"), List(Of GroupEntities.UIGroup))
            End Get
            Set(value As List(Of GroupEntities.UIGroup))
                ViewState("GroupsAvailable") = value
            End Set
        End Property

        Public Property EditedGroup As Integer
            Get

                'If ViewState("EditedGroup") Is Nothing Then
                '    ViewState("EditedGroup") = -1
                'End If

                'Return DirectCast(ViewState("EditedGroup"), Integer)

                If DnnContext.Current.AdvancedClientVariable(Me, "EditedGroup").IsNullOrEmpty() Then
                    DnnContext.Current.AdvancedClientVariable(Me, "EditedGroup") = "-1"
                End If

                Return Integer.Parse(DnnContext.Current.AdvancedClientVariable(Me, "EditedGroup"), CultureInfo.InvariantCulture)
            End Get
            Set(value As Integer)
                'ViewState("EditedGroup") = value
                DnnContext.Current.AdvancedClientVariable(Me, "EditedGroup") = value.ToString(CultureInfo.InvariantCulture)
            End Set
        End Property

        Public Property CurrentEditedType As String
            Get
                'If ViewState("CurrentEditedType") Is Nothing Then
                '    ViewState("CurrentEditedType") = "Nothing"
                'End If

                'Return DirectCast(ViewState("CurrentEditedType"), String)
                If DnnContext.Current.AdvancedClientVariable(Me, "CurrentEditedType").IsNullOrEmpty Then
                    DnnContext.Current.AdvancedClientVariable(Me, "CurrentEditedType") = "Nothing"
                End If

                Return DnnContext.Current.AdvancedClientVariable(Me, "CurrentEditedType")
            End Get
            Set(value As String)
                'ViewState("CurrentEditedType") = value
                DnnContext.Current.AdvancedClientVariable(Me, "CurrentEditedType") = value
            End Set
        End Property

        Private _SharedResourceFileOverride As String = Nothing
        Public Property SharedResourceFileOverride() As String
            Get
                If Not String.IsNullOrEmpty(_SharedResourceFileOverride) Then
                    Return _SharedResourceFileOverride
                Else
                    Return SharedResourceFile
                End If
            End Get
            Set(ByVal value As String)
                _SharedResourceFileOverride = value
            End Set
        End Property



        Public Event AvailableProvidersEvent(APEA As AvailableProvidersEventArgs)
        Public Class AvailableProvidersEventArgs
            Inherits EventArgs

            Public Property Providers As IEnumerable(Of UrlProviderInfo)
        End Class

        Public Property IncludeAliases As Boolean = True

        Public Overridable ReadOnly Property AvailableProviders As IEnumerable(Of UrlProviderInfo)
            Get
                Dim aPEA As New AvailableProvidersEventArgs()
                aPEA.Providers = FriendlierUrlConfig.Instance.AvailableUrlrewriters.Values
                RaiseEvent AvailableProvidersEvent(aPEA)
                Return aPEA.Providers
            End Get
        End Property

        Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            'TrackViewState()
            Me.ID = "ucGroups"


            BindAvailableGroups()
            If Not IsPostBack Then
                BindGroups()
            End If

            SetInnerPropertyEditor()
        End Sub

        Protected Sub BindAvailableGroups()
            Dim urlGroupsAvailable As New List(Of UrlGroup)

            'Constants
            urlGroupsAvailable.Add(New ConstantUrlGroup) 'With {.Name = DotNetNuke.Services.Localization.Localization.GetString("ConstantUrlGroup.Name", SharedResourceFileOverride), _
            '        .Decription = DotNetNuke.Services.Localization.Localization.GetString("ConstantUrlGroup.Description", SharedResourceFileOverride)})

            ' UrlPart
            For Each e As UrlPart In [Enum].GetValues(GetType(UrlPart))
                urlGroupsAvailable.Add(New UrlPartGroup() With {.UrlPartName = e}) ', .Decription = DotNetNuke.Services.Localization.Localization.GetString("UrlPart." & e.ToString(), SharedResourceFileOverride)}) 
                'TODO: faire en sorte que le tooltip provienne du fichier de ressources
            Next

            urlGroupsAvailable.Add(New QueryStringUrlGroup()) 'With {.Name = DotNetNuke.Services.Localization.Localization.GetString("QueryStringGroup.Name", SharedResourceFileOverride), _
            '     .Decription = DotNetNuke.Services.Localization.Localization.GetString("QueryStringGroup.Description", SharedResourceFileOverride)})

            'Aliases
            If IncludeAliases Then
                For Each AliasName As String In CurrentSettings.Aliases.Keys
                    urlGroupsAvailable.Add(New AliasUrlGroup() With {.AliasName = AliasName}) ', _
                    '.Decription = String.Format(DotNetNuke.Services.Localization.Localization.GetString("Alias.Description", SharedResourceFileOverride), AliasName, CurrentSettings.Aliases(AliasName).Instances.Count)}) 
                    'TODO: faire en sorte que le tooltip provienne du fichier de ressources
                Next
            End If

            ' on ajoute tous les groupes des providers
            For Each rewriterProvider As UrlProviderInfo In AvailableProviders
                For Each GPR As GroupParamsRewrite In rewriterProvider.Rewrites
                    urlGroupsAvailable.Add(New ProviderUrlGroup With {.GroupName = GPR.GroupName, .UrlProviderName = rewriterProvider.Name}) ', .Decription = GPR.LocalizedDescription})
                Next
            Next

            Me.GroupsAvailable.Clear()
            Me.GroupsAvailable.AddRange(urlGroupsAvailable.Select(Function(ug) GroupManagement.FUPGroupManagerFactory.GetGroupManager(ug).toUIGroup(ug)))

            Dim groupsData As New List(Of UIGroupGroup)
            groupsData.Add(New UIGroupGroup() With {.Name = Localization.GetString("BasicParts.Name", LocalResourceFile) _
                                                   , .Tooltip = Localization.GetString("BasicParts.Description", LocalResourceFile) _
                                                   , .Type = "BasicPartsGroup" _
                                                   , .Groups = GroupsAvailable.Select(Function(uig, index) New UIIndexedGroup With {.Position = index, .UIG = uig}).Where(Function(UIG) UIG.UIG.Type = "UrlPartGroup" OrElse UIG.UIG.Type = "QueryStringUrlGroup" OrElse UIG.UIG.Type = "ConstantUrlGroup").OrderBy(Of String)(Function(uig) uig.UIG.Type, StringComparer.OrdinalIgnoreCase)})

            If Me.IncludeAliases Then
                groupsData.Add(New UIGroupGroup() With {.Name = Localization.GetString("Aliases.Name", LocalResourceFile) _
                                                       , .Tooltip = Localization.GetString("Aliases.Description", LocalResourceFile) _
                                                       , .Type = "AliasUrlGroup" _
                                                       , .Groups = GroupsAvailable.Select(Function(uig, index) New UIIndexedGroup With {.Position = index, .UIG = uig}).Where(Function(UIG) UIG.UIG.Type = "AliasUrlGroup")})
            End If

            groupsData.AddRange(AvailableProviders.Select(Function(Provider) _
                                        New UIGroupGroup With {.Name = Provider.DisplayName, _
                                                               .Tooltip = "Provider " & Provider.DisplayName, _
                                                               .Type = Provider.Name.Replace(" ", "_"), _
                                                .Groups = urlGroupsAvailable _
                                                    .Select(Function(ug, Position) New UIIndexedGroup With {.Position = Position, .UIG = GroupManagement.FUPGroupManagerFactory.GetGroupManager(ug).toUIGroup(ug)}) _
                                                    .Where(Function(anon) anon.UIG.Type = "ProviderUrlGroup" AndAlso anon.UIG.ExtendedType = Provider.Name) _
                                    }))

            rGroups.DataSource = groupsData
            rGroups.DataBind()

        End Sub

        Protected Friend Sub BindGroups()


            rUsedGroups.DataSource = Groups.Select(Function(ug, index) New With {.Position = index, _
                                                                                 .Selected = (index = EditedGroup), _
                                                                                 .UIG = GroupManagement.FUPGroupManagerFactory.GetGroupManager(ug).toUIGroup(ug), _
                                                                                 .EditionTooltip = DotNetNuke.Services.Localization.Localization.GetString("Edition.ToolTip", LocalResourceFile), _
                                                                                 .DeletionTooltip = DotNetNuke.Services.Localization.Localization.GetString("Deletion.ToolTip", LocalResourceFile)})
            rUsedGroups.DataBind()
        End Sub


        Public Sub RaisePostBackEvent(eventArgument As String) Implements System.Web.UI.IPostBackEventHandler.RaisePostBackEvent
            UICommands.FUPCommandFactory.RetrieveCommand(eventArgument).RunCommand(Me)
        End Sub

        Public Function GetScriptDescriptors() As System.Collections.Generic.IEnumerable(Of System.Web.UI.ScriptDescriptor) Implements System.Web.UI.IScriptControl.GetScriptDescriptors
            Dim toReturn As New List(Of ScriptDescriptor)
            Dim descriptor As ScriptControlDescriptor = New ScriptControlDescriptor("Aricie.FriendlierUrlProvider.DraggableGroups", pnlFUPStrategyGroups.ClientID)

            descriptor.AddProperty("uniqueId", UniqueID)
            descriptor.AddProperty("dragSource", pnlFUPStrategyGroups.ClientID)
            descriptor.AddProperty("dragTarget", UsedGroups.ClientID)
            descriptor.AddProperty("deletionMessage", DotNetNuke.Services.Localization.Localization.GetString("Deletion.Message", LocalResourceFile))

            toReturn.Add(descriptor)
            Return toReturn
        End Function

        Public Function GetScriptReferences() As System.Collections.Generic.IEnumerable(Of System.Web.UI.ScriptReference) Implements System.Web.UI.IScriptControl.GetScriptReferences
            Dim toReturn As New List(Of ScriptReference)

            toReturn.Add(New ScriptReference(Me.ResolveUrl("../js/DraggableGroups.js")))

            Return toReturn
        End Function

        Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
            If (rUsedGroups.DataSource Is Nothing) Then
                BindGroups()
            End If

            ScriptManager.GetCurrent(Page).RegisterScriptControl(Me)
            If TrialMode IsNot Nothing Then
                'peGroup.TrialStatus = TrialMode.CurrentTrialMode
            End If

            MyBase.OnPreRender(e)
        End Sub

        Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
            MyBase.Render(writer)
            ScriptManager.GetCurrent(Page).RegisterScriptDescriptors(Me)
        End Sub

        Public Sub SetInnerPropertyEditor()
            peGroup.LocalResourceFile = SharedResourceFileOverride
            If Me.EditedGroup = -1 OrElse EditedGroup >= Groups.Count Then
                EditedGroup = -1
                CurrentEditedType = "Nothing"
                pnlProperties.Visible = False
            Else
                Dim UG As UrlGroup = Groups(EditedGroup)
                If (Me.CurrentEditedType <> UG.GetType().Name) Then
                    peGroup.ResetDatasourceType()
                    CurrentEditedType = UG.GetType().Name
                End If
                peGroup.DataSource = Groups(EditedGroup)
                pnlProperties.Visible = True
                peGroup.DataBind()
            End If
        End Sub

    End Class

End Namespace

